import random
from pypinyin import pinyin, Style
import time

# 用户类
class User:
    def __init__(self, username):
        self.username = username
        self.score = 0
        self.hint_count = 2  # 每个用户初始有2次提示机会

    def add_score(self, points):
        self.score += points

    def use_hint(self):
        if self.hint_count > 0:
            self.hint_count -= 1
            return True
        else:
            return False

    def __str__(self):
        return f"用户：{self.username}，得分：{self.score}，剩余提示次数：{self.hint_count}"

# 读取成语大全数据库
def load_idioms(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        idioms = file.readlines()
    return [idiom.strip() for idiom in idioms]

# 获取随机成语
def get_random_idiom(idioms):
    return random.choice(idioms)

# 判断成语是否在数据库中
def is_idiom_in_database(idiom, idioms):
    return idiom in idioms

# 获取机器接龙的成语
def get_machine_idiom(last_idiom, idioms):
    last_char_pinyin = pinyin(last_idiom[-1], style=Style.NORMAL)[0][0]
    available_idioms = [idiom for idiom in idioms if pinyin(idiom[0], style=Style.NORMAL)[0][0] == last_char_pinyin]

    if available_idioms:
        return random.choice(available_idioms)
    else:
        return None

# 获取提示
def get_hint(last_idiom, idioms):
    last_char_pinyin = pinyin(last_idiom[-1], style=Style.NORMAL)[0][0]
    hints = [idiom for idiom in idioms if pinyin(idiom[0], style=Style.NORMAL)[0][0] == last_char_pinyin]

    if hints:
        return random.choice(hints)
    else:
        return None

# 人机对战模式
def human_vs_machine_mode(idioms, user, time_limit=30):
    print("欢迎来到人机对战模式！")
    current_idiom = get_random_idiom(idioms)
    print(f"机器给出成语：{current_idiom}")

    while True:
        start_time = time.time()
        try:
            user_input = input("请输入接龙的成语（输入'提示'获取提示，输入'结束'结束游戏）：").strip()
        except KeyboardInterrupt:
            print("\n检测到中断信号，游戏结束！")
            break
        elapsed_time = time.time() - start_time

        if user_input == "结束":
            print("游戏结束！")
            break
        elif user_input == "提示":
            if user.use_hint():
                hint = get_hint(current_idiom, idioms)
                if hint:
                    print(f"提示：{hint}")
                else:
                    print("没有更多提示了，请继续尝试。")
                user.add_score(-5)  # 使用提示扣分
            else:
                print("您的提示次数已用完，请继续尝试。")
            continue

        # 检查是否超时
        if elapsed_time > time_limit:
            print("时间到！未在规定时间内完成接龙，机器自动接龙。")
            user.add_score(-10)  # 超时扣分
            machine_idiom = get_machine_idiom(current_idiom, idioms)
            if machine_idiom:
                print(f"机器接龙成语：{machine_idiom}")
                current_idiom = machine_idiom
            else:
                print("机器无法接龙，游戏结束！")
                break
            continue

        # 检查用户输入的成语首字是否与机器给出的成语尾字同音
        last_char_pinyin = pinyin(current_idiom[-1], style=Style.NORMAL)[0][0]
        user_first_char_pinyin = pinyin(user_input[0], style=Style.NORMAL)[0][0]
        if user_first_char_pinyin != last_char_pinyin:
            print(f"成语接龙错误，应以'{current_idiom[-1]}'的拼音开头，请重新输入。")
            user.add_score(-10)  # 接龙错误扣分
            continue

        # 检查成语是否在数据库中
        if not is_idiom_in_database(user_input, idioms):
            print("输入的成语不在数据库中。")
            continue

        print(f"用户给出成语：{user_input}")
        user.add_score(20)  # 接龙成功加分
        current_idiom = user_input

        # 机器接龙
        machine_idiom = get_machine_idiom(current_idiom, idioms)
        if machine_idiom:
            print(f"机器接龙成语：{machine_idiom}")
            current_idiom = machine_idiom
        else:
            print("机器无法接龙，游戏结束！")
            break

    print(user)

# 多人模式
def multi_player_mode(idioms, users, time_limit=30):
    print("欢迎来到多人模式！")
    current_idiom = get_random_idiom(idioms)
    print(f"当前成语：{current_idiom}")

    current_user_index = 0
    while True:
        current_user = users[current_user_index]
        print(f"当前用户：{current_user.username}")

        start_time = time.time()
        try:
            user_input = input("请输入接龙的成语（输入'结束'结束游戏）：").strip()
        except KeyboardInterrupt:
            print("\n检测到中断信号，游戏结束！")
            break
        elapsed_time = time.time() - start_time

        if user_input == "结束":
            print("游戏结束！")
            break

        # 检查是否超时
        if elapsed_time > time_limit:
            print("时间到！未在规定时间内完成接龙。")
            current_user.add_score(-10)  # 超时扣分
            current_user_index = (current_user_index + 1) % len(users)
            continue

        # 检查用户输入的成语首字是否与当前成语尾字同音
        last_char_pinyin = pinyin(current_idiom[-1], style=Style.NORMAL)[0][0]
        user_first_char_pinyin = pinyin(user_input[0], style=Style.NORMAL)[0][0]
        if user_first_char_pinyin != last_char_pinyin:
            print(f"成语接龙错误，应以'{current_idiom[-1]}'的拼音开头，请重新输入。")
            current_user.add_score(-10)  # 接龙错误扣分
            continue

        # 检查成语是否在数据库中
        if not is_idiom_in_database(user_input, idioms):
            print("输入的成语不在数据库中。")
            continue

        print(f"用户给出成语：{user_input}")
        current_user.add_score(20)  # 接龙成功加分
        current_idiom = user_input

        current_user_index = (current_user_index + 1) % len(users)

    # 游戏结束后显示所有用户的得分
    for user in users:
        print(user)

# 主函数
if __name__ == "__main__":
    file_path = 'E:/成语大全.txt'
    idioms = load_idioms(file_path)
    print(f"成语库中有 {len(idioms)} 个成语。")

    # 选择游戏模式
    mode = input("请选择游戏模式（输入'1'选择人机对战，输入'2'选择多人模式）：").strip()

    if mode == '1':
        username = input("请输入您的用户名：")
        user = User(username)
        human_vs_machine_mode(idioms, user)
    elif mode == '2':
        num_users = int(input("请输入玩家数量："))
        users = []
        for i in range(num_users):
            username = input(f"请输入玩家{i+1}的用户名：")
            users.append(User(username))
        multi_player_mode(idioms, users)
    else:
        print("输入无效，游戏结束。")